package com.hb.bussiness.service.impl;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.fastjson.JSON;
import com.hb.bussiness.dao.ElasticsearchDao;
import com.hb.bussiness.dao.impl.ElasticsearchDaoImpl;
import com.hb.bussiness.dto.CommonResponse;
import com.hb.bussiness.dto.ESEntity;
import com.hb.bussiness.service.ESSearchService;
import com.hb.bussiness.utils.ElasticClientUtil;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;

/**
 * @author hb
 * @date:2023/4/25 10:59
 */

@Service
public class ESQueryServerImpl {

    @Autowired
    private ElasticsearchDao elasticsearchDao;

    @Autowired
    private ESSearchService esSearchService ;

    public static final String RESOURCE_NAME = "sentinal_resource_name";

    private final Logger LOGGER = LoggerFactory.getLogger(ElasticsearchDaoImpl.class);


    public CommonResponse highLightQuery(Integer pageNum, Integer pageSize, String word) {

        SearchRequest searchRequest = new SearchRequest();
        ArrayList<ESEntity> esEntities = new ArrayList<>();
        //分页
        SearchSourceBuilder sourceBuilder = ElasticClientUtil.builderPageSearchBuilder(pageNum, pageSize);
        //添加高亮查询字段
        String[] searchFields = new String[]{"infoTitle"};
        ElasticClientUtil.sourceBuilderAddHighlight(sourceBuilder,searchFields);

        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.should(QueryBuilders.matchQuery("infoTitle",word));
//        boolQueryBuilder.should(QueryBuilders.matchQuery("infoContext",word));
        SearchSourceBuilder query = sourceBuilder.query(boolQueryBuilder);
        SearchRequest request = searchRequest.source(query);
        //获取结果
        SearchResponse search = elasticsearchDao.boolSearch(request);
        //结果添加高亮显示
        SearchHit[] hits = search.getHits().getHits();

        //json字符串转化为对象并将高亮结果填充
        for (SearchHit searchHit:hits) {
            String sourceAsString = searchHit.getSourceAsString();
            ESEntity esEntity = JSON.parseObject(sourceAsString, ESEntity.class);
            String infoTitle = ElasticClientUtil.buildHighlightResult(searchHit, "infoTitle", word);
            if (infoTitle != null) {
                esEntity.setInfoTitle(infoTitle);
            }
            esEntities.add(esEntity);
        }

        return CommonResponse.success(esEntities);

    }

    @SentinelResource(value = RESOURCE_NAME, blockHandler = "completionSuggestionQueryBlockHandler", fallback = "completionSuggestionQueryFallback")
    public CommonResponse completionSuggestionQuery(String word) {
        CommonResponse commonResponse = esSearchService.searchSpuSuggest(word);
        return commonResponse;
    }

    // 服务流量控制处理，注意细节，一定要跟原函数的返回值和形参一致，并且形参最后要加个BlockException参数，否则会报错，FlowException: null
    public String completionSuggestionQueryBlockHandler(String word, BlockException ex)
    {
        System.out.println("completionSuggestionQueryBlockHandler：" + ex.getMessage());
        return "{\"code\":\"500\",\"msg\": \"\" + word + \"服务流量控制处理\"}";
    }

    // 服务熔断降级处理，函数签名与原函数一致或加一个 Throwable 类型的参数
    public String completionSuggestionQueryFallback(String word, Throwable throwable)
    {
        System.out.println("completionSuggestionQueryFallback：" + throwable.getMessage());
        return "{\"code\":\"500\",\"msg\": \"" + word + "服务熔断降级处理\"}";
    }
}
